package net;

import java.text.SimpleDateFormat;
import java.util.Date;

import beans.HttpConfig;
import beans.LogEnum;
import beans.RunningTask;
import beans.TokenValue;
import dao.HistoryTaskDao;
import dao.SocketLogDao;
import engine.BIEngine0_1.AlgorithmThread;
import net.sf.json.JSONObject;
import portal.dao.ScheduleJobDetailDao;
import portal.util.SpringContextUtil;
import utils.UserLogUtil;

public class QueryThread extends Thread {
	private String taskHash;
	private String jobId;
	private String algorithmHash;
	private String status;

	public QueryThread(String taskHash, String jobId, String algorithmHash, String status) {
		this.taskHash = taskHash;
		this.jobId = jobId;
		this.algorithmHash = algorithmHash;
		this.status = status;
	}

	@Override
	public void run() {
		JSONObject resultJson = new JSONObject();
		AlgorithmThread algorithmThread = RunningTask.TASKMAP.getTask(taskHash).runningTaskBean.runningAlgorithms
				.get(algorithmHash);
		/**
		 * update job state in algorithm thread query job state and record into
		 * data base
		 */
		algorithmThread.updateJobFullState(jobId, 0);
		if(HttpConfig.synchronize){
			switch(status){
				case "0":
					status = "DONE";
					break;
				default:
					status = "ERROR";
			}
	//		ScheduleJobDetailDao scheduleJobDetailDao = SpringContextUtil.getBean(ScheduleJobDetailDao.class);//new ScheduleJobDetailDao();
			ScheduleJobDetailDao scheduleJobDetailDao = SpringContextUtil.getBean("scheduleJobDetailDao");//new ScheduleJobDetailDao();
			scheduleJobDetailDao.updateStateById(status, jobId);
		}
		/**
		 * 2018-7-14 添加socket日志查询功能，algorithmState：0：失败；1：完成；2：运行中
		 */
		// 先查询jobId对应的作业状态
		SocketLogDao socketLogDao = new SocketLogDao();
		HistoryTaskDao historyTaskDao = new HistoryTaskDao();
		String algorithmState = null;
		int time = 0;
		// 反复询问计算任务的最新状态
		while (true) {
			time++;
			// 间隔三秒询问一次
		/*	try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}*/
			// 超过30次就放弃，认定任务失败
			/*
			 * if(time==10) {
			 * socketLogDao.updateAlgorithmStateByJobId(0+"",jobId); break; }
			 */
			algorithmState = socketLogDao.queryAlgorithmStateByJobId(jobId);
			// 如果状态是运行中，就需要反复去查询任务的最新状态
			if (algorithmState.equals("2")) {
				if (HttpConfig.fake) {
					socketLogDao.updateLogFileByJobId("D:/JCPT_files/socketLog/2018-07-08-16-49-31-时间不用管-测试使用.txt",
							jobId);
					socketLogDao.updateAlgorithmStateByJobId("1", jobId);
				} else {
					String fileUrl = queryLogFileUrl();
					// 查询到日志文件地址，进一步去下载文件到本地服务器
					if (fileUrl != null) {
						// 将远端日志文件下载到本地服务器
						String newFilePath = downloadLogFile(fileUrl);
						if (newFilePath != null) {
							// 将日志文件路径记录到数据库
							if (socketLogDao.updateLogFileByJobId(newFilePath, jobId)) {
								// 将任务状态更新为完成，结束循环
								socketLogDao.updateAlgorithmStateByJobId("1", jobId);
								break;
							}
						}
					}
				}
			}
			// 如果状态是非运行中，就不需要再询问
			else {
				// 简化已完成任务的state描述
				// historyTaskDao.updateStateByTaskhash(taskHash, jobId);
				break;
			}
		}
	}

	/**
	 * 查询运行任务的日志文件地址 协议里面data是一个数组，这里只取了数组中的第一个元素 { "result": "success",
	 * "message": null, "data": [ { "fileName": "output.6084.txt", "path":
	 * "/apps/jhinno/jhappform/spoolers/jhadmin/cd35183a-a6b5-424d-b_uiAlgorithm_1_jhadmin_1522390330804/output.6084.txt"
	 * } ] }
	 * 
	 * @return 上面的path对应的字符串值
	 */
	private String queryLogFileUrl() {
		String result = null;
		String token = TokenValue.TOKEN.getTokenValue(HttpConfig.userName, HttpConfig.passWord);
		if (token != null) {
			// 请求格式：http://192.168.1.42:8080/appform/ws/jobs/flistbyid/{jobid}?token=...
			String queryUrl = HttpConfig.notCplusTaskStateQuery + jobId;
			JSONObject httpResult = JSONObject.fromObject(HttpRequest.sendGet(queryUrl, "token=" + token));
			// 该任务属于非c++平台的计算任务，并且此时已经结束，产生日志文件，需要进行记录
			if (httpResult.getString("result").equals("success")) {
				JSONObject urlArray = httpResult.getJSONArray("data").getJSONObject(0);
				result = urlArray.getString("path");
			} else {
				// 该任务要么是c++平台的计算任务，通过上述接口无法查询到状态，要么是非C++平台计算任务，但目前暂时没有结果
				return null;
			}
		} else {
			// 日志记录
			UserLogUtil.dbLog(LogEnum.system, LogEnum.query, "-2", "系统请求token时出现错误");
		}
		return result;
	}

	/**
	 * 下载运行任务的日志文件的接口 输入参数： token: 调度token path: 日志文件所在的路径 输出参数：
	 * <data contentType="application/x-msdownload" contentLength=
	 * "5573"><![CDATA[ …… 日志文件内容 …… ]]></data>
	 * 
	 * @param path：调用queryLogFileUrl方法的到的："path":
	 *            "/apps/jhinno/jhappform/spoolers/jhadmin/cd35183a-a6b5-424d-b_uiAlgorithm_1_jhadmin_1522390330804/output.6084.txt"
	 * @return
	 */
	private String downloadLogFile(String path) {
		boolean result = false;
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
		// 例子：D:/JCPT_files/socketLog/2018-06-28-15-13-06-测试.txt
		String newFilePath = HttpConfig.socketLogFileUri + sf.format(new Date()) + "-"
				+ path.substring(path.lastIndexOf("/") + 1, path.length());
		String token = TokenValue.TOKEN.getTokenValue(HttpConfig.userName, HttpConfig.passWord);
		if (token != null) {
			String param = "token=" + token + "&path=" + path;
			result = HttpRequest.downloadFile(HttpConfig.logFileDownloadUrl, param, newFilePath);
		}
		return result ? newFilePath : null;
	}

}

